﻿
#if !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_)
#define AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define	nUNICODE_BOM					0xFEFF		// Unicode "byte order mark" which goes at start of file
#define	sNEWLINE						_T("\r\n")	// New line characters
#define	sDEFAULT_UNICODE_FILLER_CHAR	"#"			// Filler char used when no conversion from Unicode to local code page is possible

class CStdioFileEx : public CStdioFile
{
public:
	CStdioFileEx();
	CStdioFileEx(LPCTSTR lpszFileName, UINT nOpenFlags);

	virtual BOOL	Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);
	virtual BOOL	ReadString(CString& rString);
	virtual void	WriteString(LPCTSTR lpsz);
	bool			IsFileUnicodeText() { return m_bIsUnicodeText; }
	ULONGLONG	    GetCharCount();
	// Additional flag to allow Unicode text writing
	void			SetCodePage(IN const UINT nCodePage);
	static          const UINT modeWriteUnicode;
	static int		GetUnicodeStringFromMultiByteString(IN LPCSTR szMultiByteString, OUT wchar_t* szUnicodeString, IN int nUnicodeBufferSize, IN int nCodePage = -1);
	static int		GetMultiByteStringFromUnicodeString(wchar_t * szUnicodeString, char* szMultiByteString, int nMultiByteBufferSize, int nCodePage = -1);
	static int		GetRequiredMultiByteLengthForUnicodeString(wchar_t * szUnicodeString, int nCodePage = -1);
	static bool     IsFileUnicode(const CString& sFilePath);
	static UINT	    GetCurrentLocaleCodePage();
protected:
	UINT	         ProcessFlags(const CString& sFilePath, UINT& nOpenFlags);
	bool		     m_bIsUnicodeText;
	UINT		     m_nFlags;
	int		         m_nFileCodePage;
	CCriticalSection m_CsRead;   //ļ
	CCriticalSection m_CsWrite;  //дļ
};

#endif // !defined(AFX_STDIOFILEEX_H__41AFE3CA_25E0_482F_8B00_C40775BCDB81__INCLUDED_)
